import { getScanTask, ScanTaskResponse } from '../services/api';

export interface TaskPollerOptions {
  interval: number; // 轮询间隔，毫秒
  maxRetries: number; // 最大重试次数
  onStatusChange?: (task: ScanTaskResponse) => void;
  onError?: (error: Error) => void;
  onComplete?: (task: ScanTaskResponse) => void;
  shouldStop?: (task: ScanTaskResponse) => boolean; // 自定义停止条件
}

export interface TaskPollerInstance {
  start: () => void;
  stop: () => void;
  isRunning: () => boolean;
  updateOptions: (options: Partial<TaskPollerOptions>) => void;
}

/**
 * 任务状态轮询服务
 * 用于实时监控任务状态变化
 */
class TaskStatusPoller {
  private pollers: Map<string, {
    timer: NodeJS.Timeout | null;
    options: TaskPollerOptions;
    retryCount: number;
    lastStatus: string | null;
    isActive: boolean;
  }> = new Map();

  /**
   * 创建任务轮询实例
   */
  createPoller(taskId: string, options: TaskPollerOptions): TaskPollerInstance {
    const defaultOptions: TaskPollerOptions = {
      interval: 3000, // 默认3秒
      maxRetries: 5
    };
    
    const finalOptions = { ...defaultOptions, ...options };

    // 如果已存在该任务的轮询，先停止
    if (this.pollers.has(taskId)) {
      this.stopPolling(taskId);
    }

    // 创建新的轮询配置
    this.pollers.set(taskId, {
      timer: null,
      options: finalOptions,
      retryCount: 0,
      lastStatus: null,
      isActive: false
    });

    const instance: TaskPollerInstance = {
      start: () => this.startPolling(taskId),
      stop: () => this.stopPolling(taskId),
      isRunning: () => this.isPollingActive(taskId),
      updateOptions: (newOptions) => this.updatePollerOptions(taskId, newOptions)
    };

    return instance;
  }

  /**
   * 开始轮询指定任务
   */
  private startPolling(taskId: string): void {
    const poller = this.pollers.get(taskId);
    if (!poller) {
      console.warn(`TaskStatusPoller: 找不到任务轮询配置: ${taskId}`);
      return;
    }

    if (poller.isActive) {
      console.warn(`TaskStatusPoller: 任务轮询已在运行: ${taskId}`);
      return;
    }

    console.log(`TaskStatusPoller: 开始轮询任务状态: ${taskId}, 间隔: ${poller.options.interval}ms`);
    poller.isActive = true;
    poller.retryCount = 0;
    
    // 立即执行一次
    this.pollTask(taskId);
  }

  /**
   * 停止轮询指定任务
   */
  private stopPolling(taskId: string): void {
    const poller = this.pollers.get(taskId);
    if (!poller) return;

    if (poller.timer) {
      clearTimeout(poller.timer);
      poller.timer = null;
    }
    
    poller.isActive = false;
    console.log(`TaskStatusPoller: 停止轮询任务状态: ${taskId}`);
  }

  /**
   * 检查轮询是否激活
   */
  private isPollingActive(taskId: string): boolean {
    const poller = this.pollers.get(taskId);
    return poller ? poller.isActive : false;
  }

  /**
   * 更新轮询选项
   */
  private updatePollerOptions(taskId: string, newOptions: Partial<TaskPollerOptions>): void {
    const poller = this.pollers.get(taskId);
    if (!poller) return;

    poller.options = { ...poller.options, ...newOptions };
    console.log(`TaskStatusPoller: 更新任务轮询配置: ${taskId}`, newOptions);
  }

  /**
   * 执行单次任务状态检查
   */
  private async pollTask(taskId: string): Promise<void> {
    const poller = this.pollers.get(taskId);
    if (!poller || !poller.isActive) return;

    try {
      const response = await getScanTask(Number(taskId));
      
      if (response.success && response.data) {
        const task = response.data;
        const currentStatus = task.status;

        // 检查状态是否发生变化
        if (poller.lastStatus !== currentStatus) {
          console.log(`TaskStatusPoller: 任务状态变化: ${taskId}, ${poller.lastStatus} -> ${currentStatus}`);
          poller.lastStatus = currentStatus;
          
          // 调用状态变化回调
          if (poller.options.onStatusChange) {
            try {
              poller.options.onStatusChange(task);
            } catch (callbackError) {
              console.error('TaskStatusPoller: 状态变化回调执行失败:', callbackError);
            }
          }
        }

        // 重置重试计数
        poller.retryCount = 0;

        // 检查是否应该停止轮询
        const shouldStop = this.shouldStopPolling(task, poller.options);
        if (shouldStop) {
          console.log(`TaskStatusPoller: 满足停止条件，停止轮询: ${taskId}, status: ${currentStatus}`);
          
          // 调用完成回调
          if (poller.options.onComplete) {
            try {
              poller.options.onComplete(task);
            } catch (callbackError) {
              console.error('TaskStatusPoller: 完成回调执行失败:', callbackError);
            }
          }
          
          this.stopPolling(taskId);
          return;
        }

        // 继续下一次轮询
        this.scheduleNextPoll(taskId);

      } else {
        throw new Error(response.message || '获取任务状态失败');
      }

    } catch (error) {
      console.error(`TaskStatusPoller: 轮询任务状态失败: ${taskId}`, error);
      poller.retryCount++;

      if (poller.retryCount >= poller.options.maxRetries) {
        console.error(`TaskStatusPoller: 达到最大重试次数，停止轮询: ${taskId}`);
        
        // 调用错误回调
        if (poller.options.onError) {
          try {
            poller.options.onError(error as Error);
          } catch (callbackError) {
            console.error('TaskStatusPoller: 错误回调执行失败:', callbackError);
          }
        }
        
        this.stopPolling(taskId);
        return;
      }

      // 重试时使用指数退避
      const retryDelay = Math.min(poller.options.interval * Math.pow(2, poller.retryCount - 1), 30000);
      console.log(`TaskStatusPoller: 将在 ${retryDelay}ms 后重试 (${poller.retryCount}/${poller.options.maxRetries}): ${taskId}`);
      
      poller.timer = setTimeout(() => this.pollTask(taskId), retryDelay);
    }
  }

  /**
   * 安排下一次轮询
   */
  private scheduleNextPoll(taskId: string): void {
    const poller = this.pollers.get(taskId);
    if (!poller || !poller.isActive) return;

    poller.timer = setTimeout(() => {
      if (poller.isActive) {
        this.pollTask(taskId);
      }
    }, poller.options.interval);
  }

  /**
   * 判断是否应该停止轮询
   */
  private shouldStopPolling(task: ScanTaskResponse, options: TaskPollerOptions): boolean {
    // 使用自定义停止条件
    if (options.shouldStop) {
      return options.shouldStop(task);
    }

    // 默认停止条件：任务已完成或失败
    const finalStates = ['COMPLETED', 'SUCCESS', 'FAILED', 'CANCELLED'];
    return finalStates.includes(task.status);
  }

  /**
   * 停止所有轮询
   */
  stopAllPolling(): void {
    console.log('TaskStatusPoller: 停止所有任务轮询');
    this.pollers.forEach((_, taskId) => {
      this.stopPolling(taskId);
    });
    this.pollers.clear();
  }

  /**
   * 获取当前活跃轮询数量
   */
  getActivePollingCount(): number {
    return Array.from(this.pollers.values()).filter(p => p.isActive).length;
  }

  /**
   * 清理已完成的轮询
   */
  cleanup(): void {
    const toRemove: string[] = [];
    this.pollers.forEach((poller, taskId) => {
      if (!poller.isActive) {
        toRemove.push(taskId);
      }
    });
    
    toRemove.forEach(taskId => {
      this.pollers.delete(taskId);
    });

    if (toRemove.length > 0) {
      console.log(`TaskStatusPoller: 清理了 ${toRemove.length} 个已完成的轮询`);
    }
  }
}

// 创建全局实例
export const taskStatusPoller = new TaskStatusPoller();

// 在页面卸载前清理所有轮询
if (typeof window !== 'undefined') {
  window.addEventListener('beforeunload', () => {
    taskStatusPoller.stopAllPolling();
  });

  // 定期清理已完成的轮询（每分钟）
  setInterval(() => {
    taskStatusPoller.cleanup();
  }, 60000);
}